package com.babayetu.myclang03grammaranalysis.utils;

import com.babayetu.myclang03grammaranalysis.lexical.BasicGrammar;
import com.babayetu.myclang03grammaranalysis.model.ASTNode;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BasicGrammarHelper {
    public static void dumpAST(ASTNode node, String indent) {
        log.info("{} type:{}, value:{}", indent,node.getType(),node.getValue());

        for (Object child: node.getChildren()) {
            if (child !=null) {
                dumpAST(((ASTNode) child), indent + "\t");
            }
        }
    }

    public static void evaluate(String code) {
        try {
            BasicGrammar basicGrammar = new BasicGrammar("Calculator");
            ASTNode tree = basicGrammar.doParse(code);

            BasicGrammarHelper.dumpAST(tree, "--");
//            evaluate(tree, "--");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 对某个AST节点求值
     * 这个其实是专为计算器程序服务的，做深度遍历计算
     * 并打印出这棵树
     * @param tree
     * @param indent
     */
    private static int evaluate(ASTNode tree, String indent) {
        int result = 0;
        log.info("evaluating ......");
        switch (tree.getType()) {
            case Programm:
                for (Object child : tree.getChildren()) {
                    result = evaluate(((ASTNode) child), indent+"\t");
                }
            break;
            case AddExpression:
                ASTNode<String> child1 = ((ASTNode) tree.getChildren().get(0));
                int leftValue = evaluate(child1, indent + "\t");
                ASTNode<String> child2 = ((ASTNode) tree.getChildren().get(1));
                int rightValue = evaluate(child2, indent + "\t");

                if (tree.getValue().equals("+")) {
                    result = leftValue + rightValue;
                } else if (tree.getValue().equals("-")) {
                    result = leftValue + rightValue;
                } else {
                    log.error("无法处理的加法表达式: {} {} {}",
                            leftValue,tree.getValue(),rightValue);
                }
            break;
            case MultipleExpression:
                child1 = ((ASTNode) tree.getChildren().get(0));
                leftValue = evaluate(child1, indent + "\t");
                child2 = ((ASTNode) tree.getChildren().get(1));
                rightValue = evaluate(child2, indent + "\t");

                if (tree.getValue().equals("*")) {
                    result = leftValue * rightValue;
                } else if (tree.getValue().equals("/")) {
                    result = leftValue / rightValue;
                } else {
                    log.error("无法处理的乘法表达式: {} {} {}",
                            leftValue,tree.getValue(),rightValue);
                }
            break;
            case BaseExpression:
                result = Integer.valueOf(((String) tree.getValue())).intValue();
            break;
            default:
        }
        log.info("计算器的最终计算结果:{}",result);
        return result;
    }

}
